package com.juzipi.framework.security.filter;

import com.juzipi.common.utils.StringUtils;
import com.juzipi.common.utils.security.SecurityUtils;
import com.juzipi.framework.web.service.TokenService;
import com.juzipi.inter.domain.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private TokenService tokenService;


    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        //获取登录用户的信息，这里是存入redis的用户信息
        LoginUser loginUser = tokenService.getLoginUser(httpServletRequest);
        if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())){
            //验证token
            tokenService.verifyToken(loginUser);
            /*
            这里说一下个人的想法，这个类是过滤器，如果请求带有token，就验证token然后传给这个UsernamePasswordAuthenticationToken 去验证并授权，
            参数就是用户，密码一般都是置为空的，权限，这里的权限可以在登录的时候给他设置上它的权限，但是它要一个 GrantedAuthority 类型的集合
            可以找一个类继承 GrantedAuthority （Role）,实现它的一个方法getAuthority ，再给LoginUser加一个字段List<Role> 就是实现GrantedAuthority的类的集合
            登录的时候查数据库验证登录的用户，（最好不要在这里查，在这里查的话每次请求都要查数据库验证用户的角色）顺带把查到的用户的角色设置到 loginUser 的List<Role> 集合，就可以放入这里了
            这里也可以自己实现鉴权
             */
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getRoleList());
            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }
        filterChain.doFilter(httpServletRequest,httpServletResponse);
    }
}
